Creating a New Role
Roles in Tupertino are managed through the RBAC (Role-Based Access Control) system, powered by Casbin. This RBAC setup helps control which actions a user can perform on specific resources within the organisation’s two-tiered structure.
In Tupertino's organisation model:
- Root organisation users can access and manage resources across the root and sub-organisations.
- Sub-organisation users are restricted to resources within their own sub-organisation and cannot access root organisation data.
This structure is managed via Casbin policies in the database and code, which can be updated as needed.
Steps to Create a New Role
To define a new role with permissions, follow these steps:
1. Define the Role in roles.service.ts
In roles.service.ts
, add the new role with appropriate permissions. Here’s an example that defines an admin role with write, read, and delete privileges for the organisation resource:
await this.setupPolicies([
{
role: 'admin',
resource: 'organisation',
action: 'write',
},
{
role: 'admin',
resource: 'organisation',
action: 'read',
},
{
role: 'admin',
resource: 'organisation',
action: 'delete',
},
// Add additional policies as needed
]);
This configuration sets permissions for admin on the organisation resource, aligning with root-level access. Similarly, define permissions for other roles based on their level of access and allowed actions.
2. Update the Casbin Policy in the Database
Once roles are defined in the code, start the backend server to automatically update the Casbin policy stored in the database.
npm run dev
This step ensures that the new or modified roles and their permissions are effectively stored and applied.
3. Protect Routes with Role-Based Restrictions
Apply role-based access control to routes using the @Roles
decorator in auth.middleware.ts
. For instance, to allow only admin users with read access to retrieve organisation details, protect the route as follows:
/**
* @summary Get an organisation by ID
* @param id - The ID of the organisation
* @returns The organisation
*/
@Get(':organisation_id')
@Roles({
roles: ['admin'],
resource: 'organisation',
action: 'read',
})
@UseInterceptors(NotFoundInterceptor)
@ApiOperation({ summary: 'Get an organisation by ID' })
findOne(@Param('organisation_id') id: string) {
return this.organisationsService.findOne(id);
}
This setup restricts access to only users with the admin role who have read permissions for the organisation resource.